package cn.t.facade.user;


import cn.t.constants.ResponseError;
import cn.t.converter.user.RoleSkuDTOConverter;
import cn.t.core.exception.BizException;
import cn.t.core.facade.FacadeImpl;
import cn.t.core.mode.PageInfoDTO;
import cn.t.core.mode.PageQueryDTO;
import cn.t.dto.device.DeviceSkuDTO;
import cn.t.dto.device.RoleSkuReq;
import cn.t.dto.device.UserRoleSkuDTO;
import cn.t.dto.sku.SkuDTO;
import cn.t.dto.user.RoleSkuDTO;
import cn.t.dto.user.SkuQtyDTO;
import cn.t.enums.PickStatusEnum;
import cn.t.facade.android.DeviceCommunicationFacade;
import cn.t.facade.device.CargowaySkuFacade;
import cn.t.facade.sku.SkuFacade;
import cn.t.model.device.CargowaySkuDO;
import cn.t.model.device.DeviceDO;
import cn.t.model.user.CustomerFirmDO;
import cn.t.model.user.ParticipantRoleDO;
import cn.t.model.user.RoleSkuDO;
import cn.t.service.device.DeviceService;
import cn.t.service.user.CustomerFirmService;
import cn.t.service.user.ParticipantRoleService;
import cn.t.service.user.RoleSkuService;
import cn.t.service.user.UserQueryService;
import cn.t.vo.andriod.AndroidDeviceVO;
import cn.t.vo.user.FirmVO;
import cn.t.vo.user.ParticipantVO;
import cn.t.vo.user.ParticipantWithUserVO;
import cn.t.vo.user.UserSessionVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 部门信息表服务编排
 *
 * @author l
 */
@Slf4j
@Service
public class RoleSkuFacade extends FacadeImpl<RoleSkuDTO, RoleSkuDO, RoleSkuDTOConverter, RoleSkuService> {

    @Override
    public boolean add(RoleSkuDTO dto) {
        validateSku(dto);
        return service.add(converter.dto2Model(dto));
    }

    @Override
    public boolean update(RoleSkuDTO dto) {
        validateSku(dto);
        return service.update(converter.dto2Model(dto));
    }

    public void validateSku(RoleSkuDTO dto) {
        UserSessionVO sessionVO = userSessionFacade.getSession();
        SkuDTO sku = existsSku(dto);
    }

    public SkuDTO existsSku(RoleSkuDTO dto) {
        SkuDTO skuDTO = new SkuDTO();
        skuDTO.setSkuCode(dto.getSkuCode());

        List<SkuDTO> results = skuFacade.queryList(skuDTO, 0, 100, null, null);

        if (CollectionUtils.isEmpty(results)) {
            return null;
        }

        return results.get(0);
    }

    public List<RoleSkuDTO> findByRoleId(Long roleId) {
        List<RoleSkuDO> list = service.findByRoleId(roleId);
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.stream().map(converter::model2Dto).collect(Collectors.toList());
    }


    /**
     * 根据 卡号、设备 查询可用的 SKU 清单
     *
     * @param firmId   企业 ID
     * @param cardCode 卡号
     * @param deviceId 设备 ID
     * @return 有权限、设备下关联的物料号清单
     */
    public List<RoleSkuDTO> findSkuByCardCode(Long firmId, String cardCode, Long deviceId) {

        // 判断企业是否存在
        CustomerFirmDO firm = customerFirmService.isExistedFirm(firmId);

        // 判断用户是否存在
        ParticipantWithUserVO participant = userQueryService.findMaterIssuerByFirmCard(firmId, cardCode);
        if (participant == null || participant.getParticipantId() == null || participant.getParticipantId() < 0) {
            return Collections.emptyList();
        }

        return findSkuByParticipantId(firmId, participant.getParticipantId(), deviceId);

    }


    public List<RoleSkuDTO> findSkuByParticipantId(Long firmId, Long participantId, Long deviceId) {
        // 获取所有领料员角色
        List<ParticipantRoleDO> participantRoleList = participantRoleService.findMetalIssueByParticipantId(participantId);
        if (CollectionUtils.isEmpty(participantRoleList)) {
            return Collections.emptyList();
        }
        Set<Long> roleIds = participantRoleList.stream().map(ParticipantRoleDO::getRoleId).collect(Collectors.toSet());

        // 获取所有领料员角色关联的物料
        List<RoleSkuDO> roleSkuList = service.findByRoleId(roleIds);
        if (CollectionUtils.isEmpty(roleSkuList)) {
            return Collections.emptyList();
        }
        Map<String, RoleSkuDO> roleSkuListMap = roleSkuList.stream().collect(Collectors.toMap(RoleSkuDO::getSkuCode, Function.identity(), (old, cur) -> old));

        DeviceDO device = deviceService.findById(deviceId);
        if (device == null || device.getFirmId() == null || !firmId.equals(device.getFirmId())) {
            return Collections.emptyList();
        }

        // 获取设备对应的 SKU 信息
        DeviceSkuDTO deviceSku = deviceService.getDeviceSku(deviceId);
        if (deviceSku == null || CollectionUtils.isEmpty(deviceSku.getSkuInfos())) {
            return Collections.emptyList();
        }


        // 两边的数据交集
        Map<String,RoleSkuDTO> ret = new HashMap<>();
        for (DeviceSkuDTO.SkuInfo skuInfo : deviceSku.getSkuInfos()) {
            RoleSkuDO roleSku = roleSkuListMap.get(skuInfo.getSkuCode());
                if (roleSku != null && StringUtils.isNotBlank(roleSku.getSkuCode()) && StringUtils.isNotBlank(skuInfo.getSkuCode()) && roleSku.getSkuCode().equals(skuInfo.getSkuCode())) {
                    RoleSkuDTO roleSkuDTO = ret.get(roleSku.getSkuCode());
                    if (roleSkuDTO != null) {
                        roleSkuDTO.setInventory(roleSkuDTO.getInventory()+skuInfo.getInventory());
                        roleSkuDTO.setRealInventory(roleSkuDTO.getRealInventory()+skuInfo.getRealInventory());
                        ret.put(skuInfo.getSkuCode(),roleSkuDTO);
                    }else {
                        RoleSkuDTO roleSkuDto = converter.model2Dto(roleSku);
                        roleSkuDto.setSkuName(skuInfo.getSkuName());
                        roleSkuDto.setInventory(skuInfo.getInventory());
                        roleSkuDto.setRealInventory(skuInfo.getRealInventory());
                        ret.put(skuInfo.getSkuCode(),roleSkuDto);
                    }


            }
        }

        return new ArrayList<>(ret.values());
    }

    public PageInfoDTO<UserRoleSkuDTO> querySkuRoleByUser(PageQueryDTO<RoleSkuReq> req, AndroidDeviceVO device) {
        //过滤出有库存的sku
        RoleSkuReq param = req.getParam();
        UserSessionVO session = userSessionFacade.getSession();
        Optional<FirmVO> first = session.getFirms().stream().filter(firm -> firm.getCustomerId().equals(device.getFirmId())).findFirst();
        Long participantId = null;
        if (first.isPresent()) {
            Optional<ParticipantVO> first1 = first.get().getParticipants().stream().findFirst();
            if (!first1.isPresent()) {
                throw new BizException(ResponseError.OPTION_DATA_RESTRICTION, ResponseError.OPTION_DATA_RESTRICTION.getName());
            }
            participantId = first1.get().getParticipantId();
        }
        List<RoleSkuDTO> skuRoleList = findSkuByParticipantId(device.getFirmId(), participantId, device.getDeviceId());

        if (!ObjectUtils.isEmpty(param.getSkuCodeOrName())){
            //根据sku 和名字 模糊查询
            skuRoleList=  skuRoleList.stream() .filter(roleSkuDTO -> StringUtils.isNotBlank(roleSkuDTO.getSkuName()) && (roleSkuDTO.getSkuName().contains(param.getSkuCodeOrName()) || roleSkuDTO.getSkuCode().contains(param.getSkuCodeOrName())))
                    .collect(Collectors.toList());
        }

        List<RoleSkuDTO> skuListN = skuRoleList.stream().distinct()
                .skip((long) req.getStart() )
                .limit( req.getPageSize())
                .collect(Collectors.toList());
        List<String> skuList = skuListN.stream().map(RoleSkuDTO::getSkuCode).distinct().collect(Collectors.toList());
        if (CollectionUtils.isEmpty(skuList)) {
            return new PageInfoDTO<>(req.getPageNo(), req.getPageSize(), 0, null);

        }

        Long deviceId = device.getDeviceId();
        List<CargowaySkuDO> cargowaySku = cargowaySkuFacade.getCargowaySkuByDeviceId(skuList, deviceId);
        skuList= cargowaySku.stream().map(CargowaySkuDO::getSkuCode).distinct().collect(Collectors.toList());
        List<CargowaySkuDO> cargowaySkuList =cargowaySku .stream().filter(cargowaySkuDO -> cargowaySkuDO.getInventory() > 0).collect(Collectors.toList());
        //按照sku分组，有库存的展示累加库存和 显示列表
        Map<String, Integer> skuCodeInventoryMap = cargowaySkuList.stream().collect(Collectors.groupingBy(CargowaySkuDO::getSkuCode, Collectors.summingInt(CargowaySkuDO::getInventory)));
        //有库存的sku去查询当前用户的历史领用情况
        List<RoleSkuDTO> skuCodeInventory = skuRoleList.stream().filter(skuCode -> skuCodeInventoryMap.containsKey(skuCode.getSkuCode())).collect(Collectors.toList());
        Map<String, RoleSkuDTO> roleSkuDTOMap = skuListN.stream().collect(Collectors.toMap(RoleSkuDTO::getSkuCode, Function.identity(), (a, b) -> b));
        Map<String, SkuQtyDTO> dayOverPickNumMap = deviceCommunicationFacade.getDayOverPickNumList(session.getUserId(), device.getFirmId(), skuCodeInventory).stream().collect(Collectors.toMap(SkuQtyDTO::getSkuCode, Function.identity(), (a, b) -> b));

        //查询sku信息
        Map<String, SkuDTO> skuMap = skuFacade.getSkuMap(skuList);

        List<UserRoleSkuDTO> userRoleSkuDo = skuList.stream().map( skuCode -> {
                    UserRoleSkuDTO skuQtyDTO1 = new UserRoleSkuDTO();
                    SkuDTO skuDTO = skuMap.get(skuCode);
                    skuQtyDTO1.setSkuCode(skuDTO.getSkuCode());
                    skuQtyDTO1.setSkuImg(skuDTO.getSkuImg());
                    skuQtyDTO1.setProductName(skuDTO.getSkuName());

                    //判断是否缺货
                    int inventory = skuCodeInventoryMap.get(skuCode)==null?0:skuCodeInventoryMap.get(skuCode);
                    RoleSkuDTO roleSkuDTO = roleSkuDTOMap.get(skuCode);
                    //已领用数量
                    Integer pickUpNum = 0;
                    //可领用数量
                    int pickUpLimit=roleSkuDTO.getLimitedQuantity();
                    skuQtyDTO1.setPickStatus(inventory>0? PickStatusEnum.PICKUP_SUCCESS.getCode():PickStatusEnum.NO_STOCK.getCode());
                    SkuQtyDTO skuQty2 = dayOverPickNumMap.get(skuCode);
                    if (skuQty2 != null) {
                        pickUpNum = skuQty2.getPickQuantity();
                        pickUpLimit= skuQty2.getLimitedQuantity() - pickUpNum;
                    }
                    if (roleSkuDTO.getLimitedType() < 0 || roleSkuDTO.getLimitedQuantity() == -1) {
                        pickUpLimit= inventory;

                    }
                    skuQtyDTO1.setPickUpNum(pickUpNum);
                    skuQtyDTO1.setPickUpLimit(pickUpLimit);
                    skuQtyDTO1.setInventory(inventory);
                    //综合本台柜子最大可领用数量,如果可领用数量大于库存，取库存为最大可领用，反之则取可领用数量
                    skuQtyDTO1.setPickUpByInventory(Math.min(inventory, pickUpLimit));

                    //可领为0
                    if (skuQtyDTO1.getPickUpLimit() <= 0 && inventory> 0) {
                        skuQtyDTO1.setPickStatus(PickStatusEnum.OVER_PICKUP.getCode());
                    }
                    skuQtyDTO1.setInventory(inventory);

                    return skuQtyDTO1;
                }).

                collect(Collectors.toList());
        //set 库存列表
        cargowaySkuFacade.getSkuInventory(cargowaySkuList, userRoleSkuDo, deviceId);
        return new PageInfoDTO<>(req.getPageNo(), req.getPageSize(), skuRoleList.size(), userRoleSkuDo);

    }

    @Autowired
    private CustomerFirmService customerFirmService;

    @Autowired
    private UserQueryService userQueryService;

    @Autowired
    private UserSessionFacade userSessionFacade;

    @Autowired
    private SkuFacade skuFacade;

    @Autowired
    private ParticipantRoleService participantRoleService;

    @Autowired
    private DeviceService deviceService;
    @Resource
    private DeviceCommunicationFacade deviceCommunicationFacade;
    @Resource
    private CargowaySkuFacade cargowaySkuFacade;

}





